package com.yuerenjf.yuerenjinfu.http;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.google.gson.Gson;
import com.qiniu.android.utils.StringUtils;
import com.yuerenjf.yuerenjinfu.activity.LoginActivity;
import com.yuerenjf.yuerenjinfu.bean.BaseBean;
import com.yuerenjf.yuerenjinfu.utils.CacheUtils;
import com.yuerenjf.yuerenjinfu.utils.ConstantUtils;

import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.image.ImageOptions;
import org.xutils.x;

import java.io.File;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.UnknownHostException;
import java.util.Map;

/**
 * Created by Administrator on 2017/6/16 0016.
 */

public class Xutils {

    private volatile static Xutils instance;
    private Handler handler;
    private ImageOptions options;

    public static final int ERROR_CODE_TOKEN_NULL=1001;
    public static final int ERROR_CODE_NO_LOGIN=1006;



    private Xutils() {
        handler = new Handler(Looper.getMainLooper());
    }

    /**
     * 单例模式
     *
     * @return
     */
    public static Xutils getInstance() {
        if (instance == null) {
            synchronized (Xutils.class) {
                if (instance == null) {
                    instance = new Xutils();
                }
            }
        }
        return instance;
    }


    /**
     * 异步get请求
     *
     * @param url
     * @param maps
     * @param callBack
     */
    public void get(final Context context, final String url, Map<String, String> maps, final XCallBack callBack) {
        final RequestParams params = new RequestParams(url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addQueryStringParameter(entry.getKey(), entry.getValue());
            }
        }
        params.addHeader("User-Agent", Constants.HEAD_REQUEST);
        params.addQueryStringParameter("access_token", CacheUtils.getString(context, ConstantUtils.SP_TOKEN));
        params.setConnectTimeout(10*1000);
        x.http().get(params, new Callback.CommonCallback<String>() {

            @Override
            public void onSuccess(String result) {
               Log.i("result",result);
                try{
                    Gson gson = new Gson();
                    BaseBean baseBean = gson.fromJson(result, BaseBean.class);
                    if (baseBean.getStatus() == 200) {
                        onSuccessResponse(result, callBack);
                    } else if(baseBean.getStatus()==ERROR_CODE_NO_LOGIN){
                        LoginActivity.launchLoginActivity(context,LoginActivity.FROM_TYPE_MAIN_TAB);
                    }else {
                        onFailer(baseBean.getStatus(),baseBean.getMessage(),callBack);
                        if(!StringUtils.isNullOrEmpty( baseBean.getMessage())){
                            Toast.makeText(context, baseBean.getMessage(), Toast.LENGTH_SHORT).show();
                        }

                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Toast.makeText(context, "返回异常", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.i("result", ex.toString());
                if (ex instanceof UnknownHostException) { // 网络错误
                    UnknownHostException httpEx = (UnknownHostException) ex;

                    Toast.makeText(context,"请检查网络设置",Toast.LENGTH_SHORT).show();
                } else { // 其他错误
                    // ...
                }

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {
                onFinsh(callBack);
            }
        });

    }


    /**
     * 异步post请求
     *
     * @param url
     * @param maps
     * @param callback
     */
    public void post(final Context context, final String url, Map<String, String> maps, final XCallBack callback) {
        HttpRequestParams params = new HttpRequestParams(context, url);

        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue());
            }
        }
        params.setConnectTimeout(10*1000);
        params.addHeader("User-Agent", Constants.HEAD_REQUEST);
        params.addBodyParameter("access_token", CacheUtils.getString(context, ConstantUtils.SP_TOKEN));
        x.http().post(params, new Callback.CommonCallback<String>() {

            @Override
            public void onSuccess(String result) {
                Log.i("result", result);
                try{
                    Gson gson = new Gson();
                    BaseBean baseBean = gson.fromJson(result, BaseBean.class);
                    if (baseBean.getStatus() == 200||Constants.URL_LOGIN.equals(url)) {
                        onSuccessResponse(result, callback);
                    } else if(baseBean.getStatus()==ERROR_CODE_NO_LOGIN){
                        LoginActivity.launchLoginActivity(context,LoginActivity.FROM_TYPE_MAIN_TAB);
                    }else {
                        if(!StringUtils.isNullOrEmpty( baseBean.getMessage())){
                            Toast.makeText(context, baseBean.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                        onFailer(baseBean.getStatus(),baseBean.getMessage(),callback);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }




            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.i("result", ex.toString());
                if (ex instanceof UnknownHostException) { // 网络错误
                    Toast.makeText(context,"请检查网络设置",Toast.LENGTH_SHORT).show();
                } else { // 其他错误
                    // ...
                }
            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {
                Log.i("result", "onFinished");
                onFinsh(callback);
            }
        });
    }


//    /**
//     * 带缓存数据的异步 get请求
//     *
//     * @param url
//     * @param maps
//     * @param pnewCache
//     * @param callback
//     */
//    public void getCache(String url, Map<String, String> maps, final boolean pnewCache, final XCallBack callback) {
//
//        RequestParams params = new RequestParams(url);
//        if (maps != null && !maps.isEmpty()) {
//            for (Map.Entry<String, String> entry : maps.entrySet()) {
//                params.addQueryStringParameter(entry.getKey(), entry.getValue());
//            }
//        }
//        x.http().get(params, new Callback.CacheCallback<String>() {
//            @Override
//            public void onSuccess(String result) {
//                onSuccessResponse(result, callback);
//            }
//
//            @Override
//            public void onError(Throwable ex, boolean isOnCallback) {
//
//            }
//
//            @Override
//            public void onCancelled(CancelledException cex) {
//
//            }
//
//            @Override
//            public void onFinished() {
//
//            }
//
//            @Override
//            public boolean onCache(String result) {
//                boolean newCache = pnewCache;
//                if (newCache) {
//                    newCache = !newCache;
//                }
//                if (!newCache) {
//                    newCache = !newCache;
//                    onSuccessResponse(result, callback);
//                }
//                return newCache;
//            }
//        });
//    }

//    /**
//     * 带缓存数据的异步 post请求
//     *
//     * @param url
//     * @param maps
//     * @param pnewCache
//     * @param callback
//     */
//    public void postCache(String url, Map<String, String> maps, final boolean pnewCache, final XCallBack callback) {
//        RequestParams params = new RequestParams(url);
//        if (maps != null && !maps.isEmpty()) {
//            for (Map.Entry<String, String> entry : maps.entrySet()) {
//                params.addBodyParameter(entry.getKey(), entry.getValue());
//            }
//        }
//
//        x.http().post(params, new Callback.CacheCallback<String>() {
//            @Override
//            public void onSuccess(String result) {
//                Log.i("onSuccess",result);
//                onSuccessResponse(result, callback);
//            }
//
//            @Override
//            public void onError(Throwable ex, boolean isOnCallback) {
//
//            }
//
//            @Override
//            public void onCancelled(CancelledException cex) {
//
//            }
//
//
//            @Override
//            public void onFinished() {
//
//            }
//
//            @Override
//            public boolean onCache(String result) {
//                Log.i("onCache",result);
//                boolean newCache = pnewCache;
//                if (newCache) {
//                    newCache = !newCache;
//                }
//                if (!newCache) {
//                    newCache = !newCache;
//                    Log.i("onCache",result);
//                    onSuccessResponse(result, callback);
//                }
//                return newCache;
//            }
//        });
//    }


//    public void bindCommonImage(ImageView iv, String url, boolean option) {
//        if (option) {
//            options = new ImageOptions.Builder().setLoadingDrawableId(R.mipmap.icon_stub).setFailureDrawableId(R.mipmap.icon_error).build();
//            x.image().bind(iv, url, options);
//        } else {
//            x.image().bind(iv, url);
//        }
//    }

//    /**
//     * 圆形图片显示
//     *
//     * @param iv
//     * @param url
//     * @param option
//     */
//    public void bindCircularImage(ImageView iv, String url, boolean option) {
//        if (option) {
//            options = new ImageOptions.Builder().setLoadingDrawableId(R.mipmap.icon_stub).setFailureDrawableId(R.mipmap.icon_error).setCircular(true).build();
//            x.image().bind(iv, url, options);
//        } else {
//            x.image().bind(iv, url);
//        }
//    }


//    /**
//     * 文件上传
//     *
//     * @param url
//     * @param maps
//     * @param file
//     * @param callback
//     */
    public void upLoadFile(String url, Map<String, String> maps, Map<String, File> file, final XCallBack callback) {
        RequestParams params = new RequestParams(url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue());
            }
        }
        if (file != null) {
            for (Map.Entry<String, File> entry : file.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue().getAbsoluteFile());
            }
        }
        // 有上传文件时使用multipart表单, 否则上传原始文件流.
        params.setMultipart(true);
        x.http().post(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                onSuccessResponse(result, callback);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });

    }


    /**
     * 文件下载
     *
     * @param url
     * @param maps
     * @param callBack
     */
    public void downLoadFile(String url, Map<String, String> maps, final XDownLoadCallBack callBack) {

        RequestParams params = new RequestParams(url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue());
            }
        }
        params.setAutoRename(true);// 断点续传
//        params.setSaveFilePath(PublicParams.SAVE_FILE_PATH);
        x.http().post(params, new Callback.ProgressCallback<File>() {
            @Override
            public void onSuccess(final File result) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (callBack != null) {
                            try {
                                callBack.onResponse(result);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                    }
                });
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (callBack != null) {
                            callBack.onFinished();
                        }
                    }
                });
            }

            @Override
            public void onWaiting() {

            }

            @Override
            public void onStarted() {

            }

            @Override
            public void onLoading(final long total, final long current, final boolean isDownloading) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (callBack != null) {
                            callBack.onLoading(total, current, isDownloading);
                        }
                    }
                });
            }
        });

    }


    /**
     * 异步get请求返回结果,json字符串
     *
     * @param result
     * @param callBack
     */
    private void onSuccessResponse(final String result, final XCallBack callBack) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onResponse(result);
                }
            }
        });
    }





    private void onFinsh(final XCallBack callBack) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onFinish();
                }
            }
        });
    }
    private void onFailer(final int status, final String result, final XCallBack callBack) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onFailer(status,result);
                }
            }
        });
    }

    public interface XCallBack {
        void onResponse(String result);

        void onFailer(int status,String result);

        void onFinish();


    }


    public interface XDownLoadCallBack extends XCallBack {
        void onResponse(File result);

        void onLoading(long total, long current, boolean isDownloading);

        void onFinished();
    }

    class GsonResponsePasare<T> implements ParameterizedType {


        public T deal(String response) {
//            Type gsonType = new ParameterizedType() {//...};//不建议该方式，推荐采用GsonResponsePasare实现ParameterizedType.因为getActualTypeArguments这里涉及获取GsonResponsePasare的泛型集合
            Type gsonType = this;

            BaseBean<T> commonResponse = new Gson().fromJson(response, gsonType);
            return commonResponse.getData();
        }

        @Override
        public Type[] getActualTypeArguments() {
            Class clz = this.getClass();
            //这里必须注意在外面使用new GsonResponsePasare<GsonResponsePasare.DataInfo>(){};实例化时必须带上{},否则获取到的superclass为Object
            Type superclass = clz.getGenericSuperclass(); //getGenericSuperclass()获得带有泛型的父类
            if (superclass instanceof Class) {
                throw new RuntimeException("Missing type parameter.");
            }
            ParameterizedType parameterized = (ParameterizedType) superclass;
            return parameterized.getActualTypeArguments();
        }

        @Override
        public Type getOwnerType() {
            return null;
        }

        @Override
        public Type getRawType() {
            return BaseBean.class;
        }
    }
}